import { Input, Space, Tree, type TreeProps } from "antd";
import {
  type ChangeEvent,
  forwardRef,
  useImperativeHandle,
  useMemo,
  useState,
} from "react";
import { useRequest } from "ahooks";
import { getMenuList } from "@/services/menu.ts";
import { deepTreeTwo, isLeaf } from "@/utils";

const MenuCheck = forwardRef((_, ref) => {
  const [keyword, setKeyword] = useState("");
  const onChange = (e: ChangeEvent<HTMLInputElement>) => {
    // 获取到输入框的值
    const value = e.target.value;
    // 复制给 keyword
    setKeyword(value);
  };

  // 获取完整的菜单数据
  const { data } = useRequest(getMenuList);
  // 做树形转换
  const treeData = useMemo(() => {
    // 1. 处理一下 list
    const list = data ? data : [];
    // 2. 基于 keyword 对 list 做过滤
    const newList = list.filter((item) => item.name.includes(keyword));
    // 3. 基于 newList 做 deepTree
    return deepTreeTwo(newList);
  }, [data, keyword]);

  // 存放当前勾选的 keys
  const [checkedKeys, setCheckedKeys] = useState<{
    checked: number[];
    halfChecked: number[];
  }>({ checked: [], halfChecked: [] });
  // 设置 checkedKeys
  const onCheck: TreeProps["onCheck"] = (checkKeys, { halfCheckedKeys }) => {
    // console.log("onCheck - checkKeys", checkKeys);
    // console.log("onCheck - halfCheckedKeys", halfCheckedKeys);
    // 要将 checkKeys 与 halfCheckedKeys 组装成一个新数组然后存储起来
    //      用什么数据来存储，主要考虑 state 还是 ref
    setCheckedKeys({
      checked: checkKeys as number[],
      halfChecked: halfCheckedKeys as number[],
    });
  };

  // 获取 checkedKeys 方法
  const get = () => {
    // 暴露 checkedKeys 中 checked 与 halfChecked 集合体
    return [...checkedKeys.checked, ...checkedKeys.halfChecked];
  };

  // 设置 checkedKeys 方法
  const set = (keys: number[]) => {
    // 1. 过滤出 keys 中的 叶子节点的 key
    const checked = keys.filter((key) => isLeaf(data || [], key));
    // console.log("checked", checked);
    // 使用 keys 赋值给 checkedKeys
    setCheckedKeys({
      checked: checked,
      halfChecked: [],
    });
  };

  // 对外暴露
  useImperativeHandle(ref, () => ({ get, set }), [checkedKeys]);

  return (
    <Space direction="vertical" style={{ display: "flex" }}>
      <Input.Search placeholder="请输入关键字" onChange={onChange} />
      {treeData.length > 0 && (
        <Tree
          checkable
          fieldNames={{ key: "key", title: "name", children: "children" }}
          treeData={treeData}
          titleRender={(node: API.MenuObject) => (
            <div>
              {node.name} - {node.id}
            </div>
          )}
          checkedKeys={checkedKeys}
          onCheck={onCheck}
        />
      )}
    </Space>
  );
});

export type MenuCheckInit = {
  get: () => number[];
  set: (keys: number[]) => void;
};

export default MenuCheck;
